<template>
  <view :class="['custom-slider', { vertical: direction === 'vertical' }]">
    <!-- 容器布局 -->
    <view class="slider-wrapper" :class="{ 'slider-wrapper-vertical': direction === 'vertical' }">
      <view @click="decrease" v-if="showButtons">
        <slot name="minus"></slot>
      </view>
      <!-- 轨道容器 -->
      <view
        @click="onTouchMove"
        class="slider-track-container"
        :class="{ 'slider-track-container-vertical': direction === 'vertical' }"
        :style="{
          height: direction === 'horizontal' ? trackHeight + 'rpx' : '100%',
          width: direction === 'vertical' ? trackHeight + 'rpx' : '100%',
        }"
      >
        <!-- 背景轨道 -->
        <view class="slider-track-bg" :class="{ 'slider-track-bg-vertical': direction === 'vertical' }"></view>
        <!-- 当前进度 -->
        <view
          class="slider-progress"
          :class="{ 'slider-progress-vertical': direction === 'vertical' }"
          :style="{
            width: direction === 'horizontal' ? thumbPosition + '%' : trackHeight + 'rpx',
            height: direction === 'vertical' ? thumbPosition + '%' : trackHeight + 'rpx',
            top: direction === 'vertical' ? 'auto' : '50%',
            bottom: direction === 'vertical' ? 0 : 'auto',
            left: direction === 'horizontal' ? 0 : '50%',
            transform: direction === 'horizontal' ? 'translate(0, -50%)' : 'translateX(-50%)',
            position: 'absolute',
          }"
        >
          <!-- 滑块 -->
          <view
            class="slider-thumb"
            :class="{ 'slider-thumb-vertical': direction === 'vertical' }"
            :style="{
              bottom: direction === 'vertical' ? 'auto' : 'auto',
            }"
            @touchstart="onTouchStart"
            @touchmove="onTouchMove"
            @touchend="onTouchEnd"
            @mousedown="onTouchStart"
            @mousemove="onTouchMove"
            @mouseup="onTouchEnd"
          >
            <slot name="thumb"></slot>
          </view>
        </view>
      </view>
      <view @click="increase" v-if="showButtons">
        <slot name="plus"></slot>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'benben-progress-slider',
  props: {
    value: {
      type: [Number, String],
      default: 0,
    },
    min: {
      type: [Number, String],
      default: 0,
    },
    max: {
      type: [Number, String],
      default: 100,
    },
    step: {
      type: [Number, String],
      default: 10,
    },
    showButtons: {
      type: Boolean,
      default: true,
    },
    direction: {
      type: String,
      default: 'horizontal',
      validator: (v) => ['horizontal', 'vertical'].includes(v),
    },
    trackHeight: {
      type: [String, Number],
      default: 20,
    }, // 新增属性：轨道高度
  },
  data() {
    return {
      progress: this.value,
      isDragging: false,
    }
  },
  computed: {
    decimalPlaces() {
      const stepStr = this.step.toString()
      const decimalIndex = stepStr.indexOf('.')
      let num = decimalIndex === -1 ? 0 : stepStr.length - decimalIndex - 1
      return num
    },
    range() {
      return this.max - this.min
    },
    valuePercent() {
      return this.progress
    },
    thumbPosition() {
      const percent = ((this.progress - this.min) / this.range) * 100
      return Math.round(Math.max(0, Math.min(100, percent)))
    },
  },
  watch: {
    value(val) {
      this.progress = val
    },
    progress(newVal) {
      this.$emit('input', newVal)
      this.$emit('change', newVal)
    },
  },
  methods: {
    increase() {
      let next = 0
      if (this.decimalPlaces == 0) {
        next = Math.min(this.max, this.progress + this.step)
      } else {
        next = Math.min(this.max, this.progress + this.step).toFixed(this.decimalPlaces)
      }
      this.progress = Number(next)
    },
    decrease() {
      let prev = 0
      if (this.decimalPlaces == 0) {
        prev = Math.max(this.min, this.progress - this.step)
      } else {
        prev = Math.max(this.min, this.progress - this.step).toFixed(this.decimalPlaces)
      }
      this.progress = Number(prev)
    },
    onTouchStart(e) {
      this.isDragging = true
    },
    onTouchMove(e) {
      if (e.type == 'click' || e.type == 'tap') this.isDragging = true
      if (!this.isDragging) return
      let touch = {
        clientX: 0,
        clientY: 0,
      }
      if (e.touches && e.touches.length > 0) {
        touch.clientX = e.touches[0].clientX
        touch.clientY = e.touches[0].clientY
      } else {
        touch.clientX = e.clientX
        touch.clientY = e.clientY
      }
      const query = uni.createSelectorQuery().in(this)
      query
        .select('.slider-track-container')
        .boundingClientRect((res) => {
          if (res) {
            let percent
            if (this.direction === 'horizontal') {
              percent = (touch.clientX - res.left) / res.width
            } else {
              const rawPercent = (touch.clientY - res.top) / res.height
              percent = 1 - rawPercent // 向上滑动对应更大值
            }
            let newValue = this.min + percent * this.range
            newValue = Math.round(newValue / this.step) * this.step
            newValue = Math.max(this.min, Math.min(this.max, newValue))
            this.progress = Number(newValue.toFixed(this.decimalPlaces))

            if (e.type == 'click') this.isDragging = false
          }
        })
        .exec()
    },
    onTouchEnd() {
      this.isDragging = false
    },
  },
}
</script>

<style scoped>
.custom-slider {
  position: relative;
  display: inline-block;
  width: inherit;
}
.custom-slider.vertical {
  height: inherit;
}
/* ===== vertical 容器布局 ===== */
.slider-wrapper {
  display: flex;
  align-items: center;
  position: relative;
}

.slider-wrapper-vertical {
  flex-direction: column-reverse;
  justify-content: center;
  height: 100%;
}

/* ===== horizontal 横向布局样式 ===== */
.slider-track-container {
  position: relative;
  flex: 1;
  height: 100%;
  margin: 0 12px;
  background-color: var(--track-wrapper-bg, #ccc);
  border-radius: 50px;
}

.slider-track-container-vertical {
  height: 100%;
  width: 100%;
  margin: 12px 0;
}

/* ===== 轨道样式 ===== */
.slider-track-bg {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
}

.slider-track-bg-vertical {
  width: auto;
  height: 100%;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
}

.slider-progress {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  height: 100%;
  background-color: var(--track-bg, #ff6600);
  border-radius: 50px;
}

.slider-progress-vertical {
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 100%;
  background-color: var(--track-bg, #ff6600);
  border-radius: 50px;
  position: absolute;
}

/* ===== 滑块样式 ===== */
.slider-thumb {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translate3d(50%, -50%, 0);
}

.slider-thumb-vertical {
  left: 50%;
  top: 0;
  /* bottom: 0; */
  right: auto;
  transform: translate(-50%, -50%);
}
</style>
